<template>
    <div id="cesium-container">
    </div>
</template>
  
<script>
export default {
    name: 'ThreeDTilesInteractivity',
    components: {},
    mounted() {
        this.initViewer()
    },
    methods: {
        async initViewer() {
            Cesium.Ion.defaultAccessToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIzM2RjYjJlOC01ZTQwLTQwODYtOTEwMy02M2U4OGEzYjQyNGUiLCJpZCI6MjI5NjUsInNjb3BlcyI6WyJhc3IiLCJnYyJdLCJpYXQiOjE1ODI0NTYwMzF9.VG2_T9ry8EnBWAh4msJ3s6m2jW_5hgAZQvfEQDh-WQs"
            window.viewer = new window.Cesium.Viewer("cesium-container", {
                // terrainProvider: new window.Cesium.CesiumTerrainProvider({
                //     url: 'http://data.mars3d.cn/terrain',
                //     requestWaterMask: true,
                //     requestVertexNormals: true
                // }),
                imageryProvider: new window.Cesium.ArcGisMapServerImageryProvider({
                    url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
                }),
                sceneMode: window.Cesium.SceneMode.SCENE3D,
                vrButton: false,
                animation: false,
                baseLayerPicker: false,
                geocoder: false,
                timeline: false,
                fullscreenButton: false,
                homeButton: false,
                creditContainer: document.createElement('div'),
                infoBox: false,
                navigationHelpButton: false,
                sceneModePicker: false,
                scene3DOnly: true,
                skyBox: new window.Cesium.SkyBox({
                    sources: {
                        positiveX: require('@/assets/images/tycho2t3_80_px.jpg'),
                        negativeX: require('@/assets/images/tycho2t3_80_mx.jpg'),
                        positiveY: require('@/assets/images/tycho2t3_80_py.jpg'),
                        negativeY: require('@/assets/images/tycho2t3_80_my.jpg'),
                        positiveZ: require('@/assets/images/tycho2t3_80_pz.jpg'),
                        negativeZ: require('@/assets/images/tycho2t3_80_mz.jpg'),
                    }
                })
            });


            const scene = window.viewer.scene;
            if (!scene.pickPositionSupported) {
                window.alert("This browser does not support pickPosition.");
            }

            scene.globe.depthTestAgainstTerrain = true;


            const annotations = scene.primitives.add(new window.Cesium.LabelCollection());

            // Set the initial camera view to look at Manhattan
            const initialPosition = window.Cesium.Cartesian3.fromDegrees(
                -74.01881302800248,
                40.69114333714821,
                753
            );
            const initialOrientation = new window.Cesium.HeadingPitchRoll.fromDegrees(
                21.27879878293835,
                -21.34390550872461,
                0.0716951918898415
            );
            scene.camera.setView({
                destination: initialPosition,
                orientation: initialOrientation,
                // endTransform: window.Cesium.Matrix4.IDENTITY,
            });

            // Load the NYC buildings tileset.
            const tileset = new window.Cesium.Cesium3DTileset({
                url: window.Cesium.IonResource.fromAssetId(75343),
            });
            scene.primitives.add(tileset);
            tileset.style = new window.Cesium.Cesium3DTileStyle({
                meta: {
                    description: "'Building ${BIN} has height ${Height}.'",
                },
            });

            const handler = new window.Cesium.ScreenSpaceEventHandler(window.viewer.canvas);

            handler.setInputAction(function (movement) {
                const feature = scene.pick(movement.position);
                if (!window.Cesium.defined(feature)) {
                    return;
                }

                const action = 'zoom';
                if (action === "annotate") {
                    annotate(movement, feature);
                } else if (action === "properties") {
                    printProperties(movement, feature);
                } else if (action === "zoom") {
                    zoom(movement, feature);
                }
            }, window.Cesium.ScreenSpaceEventType.RIGHT_CLICK);

            handler.setInputAction(function (movement) {
                const feature = scene.pick(movement.position);
                if (!window.Cesium.defined(feature)) {
                    return;
                }

                const action = 'hide';
                if (action === "hide") {
                    feature.show = false;
                }
            }, window.Cesium.ScreenSpaceEventType.MIDDLE_CLICK);

            function annotate(movement) {
                if (scene.pickPositionSupported) {
                    const cartesian = scene.pickPosition(movement.position);
                    if (window.Cesium.defined(cartesian)) {
                        const cartographic = window.Cesium.Cartographic.fromCartesian(cartesian);
                        const height = `${cartographic.height.toFixed(2)} m`;

                        annotations.add({
                            position: cartesian,
                            text: height,
                            showBackground: true,
                            font: "14px monospace",
                            horizontalOrigin: window.Cesium.HorizontalOrigin.LEFT,
                            verticalOrigin: window.Cesium.VerticalOrigin.BOTTOM,
                            disableDepthTestDistance: 1000,
                        });
                    }
                }
            }

            function printProperties(movement, feature) {
                console.log("Properties:");
                const propertyIds = feature.getPropertyIds();
                const length = propertyIds.length;
                for (let i = 0; i < length; ++i) {
                    const propertyId = propertyIds[i];
                    console.log(`  ${propertyId}: ${feature.getProperty(propertyId)}`);
                }

                // Evaluate feature description
                console.log(
                    `Description : ${tileset.style.meta.description.evaluate(feature)}`
                );
            }

            function zoom(movement, feature) {
                const longitude = window.Cesium.Math.toRadians(
                    feature.getProperty("Longitude")
                );
                const latitude = window.Cesium.Math.toRadians(
                    feature.getProperty("Latitude")
                );
                const height = feature.getProperty("Height");

                const positionCartographic = new window.Cesium.Cartographic(
                    longitude,
                    latitude,
                    height * 0.5
                );
                const position = scene.globe.ellipsoid.cartographicToCartesian(
                    positionCartographic
                );

                const camera = scene.camera;
                const heading = camera.heading;
                const pitch = camera.pitch;

                const offset = offsetFromHeadingPitchRange(
                    heading,
                    pitch,
                    height * 2.0
                );

                const transform = window.Cesium.Transforms.eastNorthUpToFixedFrame(position);
                window.Cesium.Matrix4.multiplyByPoint(transform, offset, position);

                camera.flyTo({
                    destination: position,
                    orientation: {
                        heading: heading,
                        pitch: pitch,
                    },
                    easingFunction: window.Cesium.EasingFunction.QUADRATIC_OUT,
                });
            }

            function offsetFromHeadingPitchRange(heading, pitch, range) {
                pitch = window.Cesium.Math.clamp(
                    pitch,
                    -window.Cesium.Math.PI_OVER_TWO,
                    window.Cesium.Math.PI_OVER_TWO
                );
                heading = window.Cesium.Math.zeroToTwoPi(heading) - window.Cesium.Math.PI_OVER_TWO;

                const pitchQuat = window.Cesium.Quaternion.fromAxisAngle(
                    window.Cesium.Cartesian3.UNIT_Y,
                    -pitch
                );
                const headingQuat = window.Cesium.Quaternion.fromAxisAngle(
                    window.Cesium.Cartesian3.UNIT_Z,
                    -heading
                );
                const rotQuat = window.Cesium.Quaternion.multiply(
                    headingQuat,
                    pitchQuat,
                    headingQuat
                );
                const rotMatrix = window.Cesium.Matrix3.fromQuaternion(rotQuat);

                const offset = window.Cesium.Cartesian3.clone(window.Cesium.Cartesian3.UNIT_X);
                window.Cesium.Matrix3.multiplyByVector(rotMatrix, offset, offset);
                window.Cesium.Cartesian3.negate(offset, offset);
                window.Cesium.Cartesian3.multiplyByScalar(offset, range, offset);
                return offset;
            }
        }
    }
}
</script>
  
<style>
#cesium-container {
    width: 100%;
    height: 100%;
}
</style>
  